package net.borderwars.util;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Timer;
import java.util.TimerTask;

/**
 * @author Eric
 *         Date: Apr 24, 2005
 *         Time: 8:16:16 PM
 */
public class ExpiringSet extends HashSet {
    HashMap<Object, Expired> data = new HashMap<Object, Expired> ();

    long timeout = 0;

    Timer t = new Timer ("ExpiringSet, true");

    HashSet<ExpireListener> listeners = new HashSet<ExpireListener> ();

    public void addListener (ExpireListener e) {
        listeners.add (e);
    }

    public void removeListener (ExpireListener e) {
        listeners.remove (e);
    }

    public ExpiringSet (long timeout) {
        this.timeout = timeout;
    }

    public void clear () {
        super.clear ();    //To change body of overridden methods use File | Settings | File Templates.
        data.clear ();
    }

    public boolean add (Object key) {
        synchronized (data) {
            if (!data.containsKey (key)) {
                Expired e = new Expired (key);
                t.schedule (e, timeout);
                data.put (key, e);
            }
            else {
                refresh (key);
            }
        }
        return (super.add (key));
    }

    public void refresh (Object key) {
        synchronized (data) {
            Expired e = data.get (key);
            e.cancel ();
            e = new Expired (key);
            t.schedule (e, timeout);
            data.put (key, e);
        }
    }

    public class Expired extends TimerTask {
        Object key = null;

        public Expired (Object key) {
            this.key = key;
        }

        public void run () {
            synchronized (data) {
                data.remove (key);
                ExpiringSet.this.remove (key);
                for (ExpireListener e : listeners) {
                    e.expired (key);
                }
            }
        }
    }

}
